package com.oliver.proxy.midjourney.application.service;

import com.oliver.proxy.midjourney.domain.entity.Prod;
import com.oliver.proxy.midjourney.event.DiscordInitializationCompletedEvent;
import com.oliver.proxy.midjourney.infrastructure.mapper.ProdMapper;
import com.oliver.proxy.midjourney.interfaces.controller.SubmitController;
import com.oliver.proxy.midjourney.interfaces.dto.SubmitImagineDTO;
import com.oliver.proxy.midjourney.loadbalancer.DiscordLoadBalancer;
import com.oliver.proxy.midjourney.result.SubmitResultVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.PostConstruct;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ProdProcessingService {
    private final ProdMapper prodMapper;
    private final SubmitController submitController;
    private final DiscordLoadBalancer discordLoadBalancer;
    private static final long PROCESSING_INTERVAL = 5000; // 5秒间隔，防止触发风控
    private final AtomicBoolean isProcessing = new AtomicBoolean(false);
    private final AtomicBoolean isInitialized = new AtomicBoolean(false);

    @Autowired
    public ProdProcessingService(ProdMapper prodMapper, SubmitController submitController, DiscordLoadBalancer discordLoadBalancer) {
        this.prodMapper = prodMapper;
        this.submitController = submitController;
        this.discordLoadBalancer = discordLoadBalancer;
    }

    @EventListener
    public void onDiscordInitializationCompleted(DiscordInitializationCompletedEvent event) {
        log.info("Discord initialization completed, starting ProdProcessingService");
        isInitialized.set(true);
    }

    @PostConstruct
    @Scheduled(fixedRate = 5000) // 每5秒执行一次
//    @Transactional
    public void processUnhandledProds() {
        if (!isInitialized.get()) {
            log.debug("Waiting for Discord initialization to complete");
            return;
        }

        // 检查是否有可用的Discord实例
        if (discordLoadBalancer.getAliveInstances().isEmpty()) {
            log.debug("No available Discord instances, skipping processing");
            return;
        }

        if (!isProcessing.get()) {
            CompletableFuture.runAsync(this::processProdsInBackground);
        }
    }

    private void processProdsInBackground() {
        if (isProcessing.compareAndSet(false, true)) {
            try {
                // 获取所有未处理的prod（prompt不为空且attritube_1为空的记录）
                // 需要联表查询以获取taskType信息
                List<Prod> unhandledProds = prodMapper.selectUnhandledProds();
                if (unhandledProds.isEmpty()) {
                    return;
                }

                // 按taskId和batch分组
                Map<String, List<Prod>> groupedProds = unhandledProds.stream()
                        .collect(Collectors.groupingBy(prod ->
                                prod.getTaskId() + "_" + prod.getBatch()));

                // 处理每个batch
                for (List<Prod> batchProds : groupedProds.values()) {
                    if (batchProds.size() == 4) {  // 确保每组正好4条记录
                        processBatchAndPersist(batchProds);
                        // 处理完一个batch后等待5秒，确保严格遵守调用间隔
                        // anti风控 随机暂停1-3秒
                        int i = new Random().nextInt(3000 - 1000) + 1000;
                        Thread.sleep(i);
                        Thread.sleep(PROCESSING_INTERVAL);
                    } else {
                        log.warn("Skipping batch with size {}, expected 4 records", batchProds.size());
                    }
                }
            } catch (Exception e) {
                log.error("Error processing unhandled prods", e);
            } finally {
                isProcessing.set(false);
            }
        }
    }

    //    @Transactional
    public void processBatchAndPersist(List<Prod> batchProds) {
        try {
            // 获取第一条记录的prompt（同一batch的prompt都是一样的）
            String prompt = batchProds.get(0).getPrompt();
            if (prompt == null || prompt.trim().isEmpty()) {
                return;
            }

            // 创建SubmitImagineDTO对象
            SubmitImagineDTO imagineDTO = new SubmitImagineDTO();
            imagineDTO.setPrompt(prompt);

            // 调用imagine方法
            SubmitResultVO response = submitController.imagine(imagineDTO);
            log.warn("prompt: {}, 发送成功", prompt);

            if (response != null) {
                // 更新所有相关记录
                for (Prod prod : batchProds) {
                    prod.setAttritube6("SUCCESS");
                    if (null == response.getResult()) {
                        // 只有当taskType为0时才设置attribute6
                        if (prod.getTaskType() != null && prod.getTaskType() == 0) {
                            prod.setAttritube6(response.getProperties().toString());
                        } else {
                            prod.setTitle(null);
                            prod.setPrompt(null);
                        }
                    }
                    prod.setAttritube1(response.getResult());
                    prod.setAttritube2(response.getProperty("discordInstanceId", String.class));
                }

                // 立即批量更新这4条记录
                prodMapper.batchUpdate(batchProds);
                log.info("Batch processed and persisted, taskId: {}, batch: {}",
                        batchProds.get(0).getTaskId(), batchProds.get(0).getBatch());
            }
        } catch (Exception e) {
            log.error("Error processing batch for taskId: {} and batch: {}",
                    batchProds.get(0).getTaskId(),
                    batchProds.get(0).getBatch(),
                    e);
            throw e; // 抛出异常以触发事务回滚
        }
    }
}
